package example.jjwt;

import grpc.htsoft.helloworld.GreeterGrpc;
import grpc.htsoft.helloworld.HelloReply;
import grpc.htsoft.helloworld.HelloRequest;
import io.grpc.Grpc;
import io.grpc.InsecureServerCredentials;
import io.grpc.Server;
import io.grpc.stub.StreamObserver;

import java.io.IOException;
import java.util.logging.Logger;

public class AuthServer {

    private static final Logger logger = Logger.getLogger(AuthServer.class.getName());

    private Server server;
    private int port;

    public AuthServer(int port) {
        this.port = port;
    }

    private void start() throws IOException {
        server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
                .addService(new GreeterImpl())
                .intercept(new JwtServerInterceptor())  // add the JwtServerInterceptor
                .build()
                .start();
        logger.info("Server started, listening on " + port);
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                // Use stderr here since the logger may have been reset by its JVM shutdown hook.
                System.err.println("*** shutting down gRPC server since JVM is shutting down");
                AuthServer.this.stop();
                System.err.println("*** server shut down");
            }
        });
    }

    private void stop() {
        if (server != null) {
            server.shutdown();
        }
    }

    /**
     * Await termination on the main thread since the grpc library uses daemon threads.
     */
    private void blockUntilShutdown() throws InterruptedException {
        if (server != null) {
            server.awaitTermination();
        }
    }

    /**
     * Main launches the server from the command line.
     */
    public static void main(String[] args) throws IOException, InterruptedException {

        // The port on which the server should run
        int port = 50051; // default
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        }

        final AuthServer server = new AuthServer(port);
        server.start();
        server.blockUntilShutdown();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
            // get client id added to context by interceptor
            String clientId = Constant.CLIENT_ID_CONTEXT_KEY.get();
            logger.info("Processing request from " + clientId);
            HelloReply reply = HelloReply.newBuilder().setMessage("Hello, " + req.getName()).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}